import React, { useState, useMemo } from 'react';
import { export_xlsx, KFile, loc, sn_name, obj_str, no_del, BtTxt, PanelFind, ParaView, filter_row, useCmd,
    useHigh, Btn, GridTable } from 'sui';
import { DlgVal } from './ctl';
import { AttrView } from './attr';
import { useAccess } from 'cache';

const BaseView = ({ colwidth=220, setEvent, title, mod, prop=true, attr, acc }) => {
    const [open_val, openVal] = useState(false);
    const [high] = useHigh(140, 100);
    const umd = useCmd(`file/list/${mod}`);
    const [no_acc] = useAccess();

    const getRow = useMemo(() => {
        const lst = ["sn", "name"];
        return filter_row(umd.value, lst, umd.filter);
    }, [umd.value, umd.filter]);

    if (umd.isFin("para")) {
        return <ParaView cur={umd.cur} hreturn={umd.hreturn} subtitle={loc("l_194")} mod={mod}/>;
    }

    if (umd.isFin("attr")) {
        const hreturn = (v) => {
            if (v) {
                if (setEvent) {
                    setEvent("ubind");
                }
            }

            umd.hreturn();
        };

        return <AttrView cur={umd.cur} hreturn={hreturn} subtitle={loc("l_683")} attr={attr} mod={mod}/>;
    }

    const hDel = (val) => {
        if (no_del()) {
            return;
        }

        umd.update(`file/rm/${mod}`, {
            sn: obj_str(val, "sn"),
        }, () => {
            if (setEvent) {
                setEvent("trace");
            }
        });
    };

    const update = (d) => {
        umd.update(`file/md/${mod}`, {
            v: d,
            sn: obj_str(d, "sn"),
        }, () => {
            if (setEvent) {
                setEvent("trace");
            }
        });
    };

    const hExport = (d) => {
        const col = ["sn", "name"];
        const ret = [
            {sn: "sn", name: obj_str(d, "sn")},
            {sn: "name", name: obj_str(d, "name")},
        ];

        if (d.para) {
            d.para.forEach(d => ret.push(d));
        }

        export_xlsx(ret, col, sn_name(d), umd);
    };

    const hImport = (val) => {
        umd.startWait();

        const set = new Set();
        const ret = [];

        let m_sn = "";
        let m_name = "";

        for (let i = 0; i < val.length; i++) {
            const d = val[i];

            const sn = obj_str(d, "sn");
            const name = obj_str(d, "name");

            if (set.has(sn)) {
                umd.setErr(`${loc("l_620")}: ${sn}`);
                return;
            }

            if (!sn || !name) {
                umd.setErr(`${loc("l_276")}, sn: ${sn}, name: ${name}`);
                return;
            }

            if (sn === "sn") {
                m_sn = name;
                continue;
            }

            if (sn === "name") {
                m_name = name;
                continue;
            }

            ret.push({sn: sn, name: name});
        }

        if (!m_sn || !m_name) {
            umd.setErr(`${loc("l_276")}, sn: ${m_sn}, name: ${m_name}`);
            return;
        }

        update({
            sn: m_sn,
            name: m_name,
            para: ret
        });
    };

    const act = {
        "add": d => update(d),
        "edit": d => update(d),
    };

    const pact = {
        "add": v => openVal(true),
        "edit": v => openVal(true),
    };

    const col = [
        {name: loc("l_193"), key: 'index', width: 70, frozen: true},
        {name: loc("l_238"), key: 'e_opt', width: colwidth, frozen: true, formatter: (props) => {
            const d = props.row;

            const getProp = () => {
                if (prop) {
                    return <BtTxt hcmd={() => umd.pact(pact, d, "para")} disabled={no_acc(acc)}>{loc("l_194")}</BtTxt>;
                }

                return null;
            };

            const getAttr = () => {
                if (attr) {
                    return <BtTxt hcmd={() => umd.pact(pact, d, "attr")} disabled={no_acc(acc)}>{loc("l_683")}</BtTxt>;
                }

                return null;
            };

            return (
                <div className="inline-flex">
                    <BtTxt hcmd={() => umd.pact(pact, d, "edit")} disabled={no_acc(acc)}>{loc("l_235")}</BtTxt>
                    <BtTxt hcmd={() => hDel(d)} disabled={no_acc(acc)}>{loc("l_237")}</BtTxt>
                    {getProp()}
                    {getAttr()}
                    <BtTxt hcmd={() => hExport(d)} disabled={no_acc(acc)}>{loc("l_519")}</BtTxt>
                </div>
            );
        }},
        {name: loc("l_495"), key: 'sn', width: 200},
        {name: loc("l_228"), key: 'name', width: 200},
    ];

    const Right = () => {
        const getRow = () => {
            if (prop) {
                return [
                    {sn: "sn", name: loc("l_608")},
                    {sn: "name", name: loc("l_228")},
                    {sn: "k1", name: `${loc("l_194")}1`},
                    {sn: "k2", name: `${loc("l_194")}2`},
                ];
            }

            return [
                {sn: "sn", name: loc("l_608")},
                {sn: "name", name: loc("l_228")},
            ];
        };

        return (
            <div className="inline-flex">
                <KFile umd={umd} title={title} col={["sn", "name"]} row={getRow()} hcmd={hImport} out={false}
                       no_acc_in={no_acc(acc)} no_acc_out={no_acc(acc)}/>
                <Btn className="ml-3" hcmd={() => umd.pact(pact, null, "add")} disabled={no_acc(acc)}>{loc("l_239")}</Btn>
            </div>
        );
    };

    return (
        <div className="flex flex-col">
            <PanelFind left={title} right={<Right/>} hcmd={umd.setFilter}/>
            <GridTable high={high} col={col} row={getRow}/>
            <DlgVal open={open_val} hcmd={v => umd.act(act, v)} setOpen={openVal} data={umd.cur} main={umd.value}/>
        </div>
    );
};

export {BaseView};
